<template>
  <div class="main">
    <div class="title">
      <div class="titleText">每小时预报</div>
      <div class="titleContainer">
        <el-radio-group v-model="metricType" size="large">
          <el-radio-button label="概览" />
          <el-radio-button label="降水" />
          <el-radio-button label="风速" />
          <el-radio-button label="湿度" />
          <el-radio-button label="云量" />
          <el-radio-button label="气压" />
          <!-- <el-radio-button label="可见度" /> -->
          <!-- <el-radio-button label="紫外线" />
          <el-radio-button label="体感温度" /> -->
        </el-radio-group>
      </div>
    </div>
    <div class="tabsCarouselItems">
      <div class="tabsContainer">
        <div class="content">
          <button class="scrollToleft" @click="moveToleft" style="display: none">&lt;</button>
          <!-- TODO:此处有一个按钮 -->
          <button class="scrollToright" @click="moveToright" style="display: none">&gt;</button>
          <div class="tabsCarousel" ref="containner">
            <!-- 每一项 -->
            <div
              class="tabsCarouselItems-DS"
              v-for="(value, index) in future"
              :key="JSON.stringify(value.fxDate)"
              :class="{ active: selectedIdx === index }"
              @click="selectedIdx = index"
            >
              <div class="tabDailyItem-DS">
                <div class="tabDailyItemBg">
                  <div class="tabDailyItemBgContent-DS"></div>
                </div>
                <!-- 内容 -->
                <div class="tabDailyButton">
                  <div class="tabContent">
                    <!-- TODO:头部 -->
                    <div class="dateSection">
                      <div>{{ value.fxDate.split('-')[2] }}</div>
                      <div>{{ getDateLabel(value.fxDate) }}</div>
                    </div>
                    <!-- TODO:内容 -->
                    <div class="conditionSection" v-if="metricType === '概览'">
                      <!-- TODO:图标 -->
                      <div class="tempIco">
                        <div v-if="selectedIdx === index">
                          <el-tooltip :content="`白天：${value.textDay}`" placement="top">
                            <i
                              :class="`qi-${value?.iconDay || 110}-fill`"
                              style="margin-right: 5px"
                            ></i>
                          </el-tooltip>
                          <el-tooltip :content="`夜晚：${value.textNight}`">
                            <i :class="`qi-${value?.iconNight || 110}-fill`"></i>
                          </el-tooltip>
                        </div>

                        <div v-else>
                          <i :class="`qi-${value?.iconDay || 110}-fill`"></i>
                        </div>
                      </div>
                      <!-- TODO:温度 -->
                      <div class="tempArea">
                        <el-tooltip content="最高温度" placement="top" v-if="selectedIdx === index">
                          <div>{{ value?.tempMax }}°</div>
                        </el-tooltip>
                        <el-tooltip
                          content="最低温度"
                          placement="bottom"
                          v-if="selectedIdx === index"
                        >
                          <div>{{ value?.tempMin }}°</div>
                        </el-tooltip>
                        <div v-else>
                          <div>{{ value?.tempMax }}°</div>
                          <div>{{ value?.tempMin }}°</div>
                        </div>
                      </div>
                    </div>
                    <!-- 降雨样式 -->
                    <div :class="CardChenage(metricType, value).className" v-else>
                      <div class="left">
                        <el-tooltip effect="dark" placement="top">
                          <div
                            class="left-ico"
                            v-show="metricType == '风速'"
                            :style="{
                              width: '30px',
                              height: '30px',
                              fontSize: '24px',
                              transform: 'rotate(' + value.wind360Day + 'deg)',
                              display: 'flex',
                              justifyContent: 'center',
                              alignItems: 'center',
                            }"
                          >
                            <i
                              class="iconfont icon-tianqi-fengxiang-copy"
                              style="font-size: 30px"
                            ></i>
                          </div>
                          <template #content>
                            <span>风向 {{ value.windDirDay }}</span>
                          </template>
                        </el-tooltip>
                        <span class="left-data">
                          <div class="defaultData">
                            <el-tooltip effect="dark" placement="bottom">
                              {{ metricType }}
                              {{ CardChenage(metricType, value).data }}
                              {{ CardChenage(metricType, value).unit }}
                              <template #content>
                                <!-- 单独定义每一个选项的视图 -->
                                <div class="changeData" v-if="metricType == '降水'">
                                  <span>最大降水量：{{ dailyMaxMinCache[index]?.Max || 0 }}</span
                                  ><br />
                                  <span>最小降水量：{{ dailyMaxMinCache[index]?.Min || 0 }}</span>
                                </div>
                                <div class="changeData" v-else-if="metricType == '风速'">
                                  <span>最大风速：{{ dailyMaxMinCache[index]?.Max || 0 }}</span>
                                  <br />
                                  <span>最小风速：{{ dailyMaxMinCache[index]?.Min || 0 }}</span>
                                </div>
                                <div class="changeData" v-else-if="metricType == '湿度'">
                                  <span>最大湿度：{{ dailyMaxMinCache[index]?.Max || 0 }}</span>
                                  <br />
                                  <span>最小湿度：{{ dailyMaxMinCache[index]?.Min || 0 }}</span>
                                </div>
                                <div class="changeData" v-else-if="metricType == '云量'">
                                  <span>最大云量：{{ dailyMaxMinCache[index]?.Max || 0 }}</span>
                                  <br />
                                  <span>最小云量：{{ dailyMaxMinCache[index]?.Min || 0 }}</span>
                                </div>
                                <div class="changeData" v-else-if="metricType == '气压'">
                                  <span>最高气压：{{ dailyMaxMinCache[index]?.Max || 0 }}</span>
                                  <br />
                                  <span>最低气压：{{ dailyMaxMinCache[index]?.Min || 0 }}</span>
                                </div>
                              </template>
                            </el-tooltip>
                          </div>
                        </span>
                      </div>
                      <div class="right">
                        <!-- 50mm以上为暴雨 ，-->
                        <div
                          class="right-level"
                          ref="StyleRef"
                          :style="{ height: CardChenage(metricType, value)?.percentage + '%' }"
                        ></div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div class="illustration-T illustration" ref="chartRef"></div>
    </div>
  </div>
</template>
<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount, watch, nextTick, watchEffect, computed } from 'vue'
import * as echarts from 'echarts'
import type { DailyFuture, Hourly, IHourlyWeather } from '@/types/weather'
import { useWeatherStore } from '@/stores/weather'
import { getDateLabel, getMetricUnit, generateHourlySeriesData, CardChenage } from './services'

const weatherStore = useWeatherStore()
// 顶部指标选择：默认"降水"
const metricType = ref<
  '降水' | '风速' | '湿度' | '云量' | '气压' | '紫外线' | '可见度' | '体感温度' | '概览'
>('概览')

const selectedIdx = ref<number>(0)
// 未来天气
const future = ref<DailyFuture[] | null>(null)
// 小时信息
const HourlyWeather = ref<IHourlyWeather | null>(null)
watchEffect(() => {
  future.value = weatherStore.currentLocation?.future?.daily
  HourlyWeather.value = weatherStore.currentLocation?.HourlyWeather
})

watch(
  () => weatherStore.currentLocationId,
  () => {
    renderChart()
  },
)
// 图表 DOM 和实例
const chartRef = ref<HTMLDivElement | null>(null)
let chartInstance: echarts.ECharts | null = null
// 渲染图表
function renderChart() {
  if (!chartRef.value) return
  if (!chartInstance) {
    chartInstance = echarts.init(chartRef.value)
  }

  const { hours, seriesData } = generateHourlySeriesData(
    HourlyWeather.value?.hourly || null,
    metricType.value,
    selectedIdx.value,
  )
  const unit = getMetricUnit(metricType.value)
  /** @type EChartsOption */
  const option: echarts.EChartsOption = {
    grid: { left: 40, right: 16, top: 40, bottom: 36 },
    tooltip: {
      trigger: 'axis',
      axisPointer: { type: 'cross' },
      valueFormatter: (val) => (val != null ? `${val}${unit}` : '-'),
    },
    xAxis: {
      type: 'category',
      data: hours,
      axisLabel: { interval: 1 },
    },
    yAxis: {
      type: 'value',
      name: unit ? `${metricType.value} (${unit})` : metricType.value,
      nameGap: 12,
      splitLine: { show: true },
      nameTextStyle: {
        fontSize: 16,
      },
    },
    series: [
      {
        name: metricType.value === '概览' ? '温度' : metricType.value,
        type: 'line',
        data: seriesData,
        smooth: true,
        symbol: 'circle',
        symbolSize: 8,
        lineStyle: {
          width: 3,
        },
        areaStyle: {
          opacity: 0.3,
        },
        emphasis: {
          focus: 'series',
          itemStyle: {
            borderWidth: 2,
            borderColor: '#fff',
          },
        },
      },
    ],
  }

  chartInstance.setOption(option)
  nextTick(() => chartInstance && chartInstance.resize())
}
// 销毁图表
function disposeChart() {
  if (chartInstance) {
    chartInstance.dispose()
    chartInstance = null
  }
}

let resizeObserver: ResizeObserver | null = null
const containner = ref<HTMLDivElement | null>(null)
// 向右移动
function moveToright() {
  console.log('moveToright', containner.value)
  containner.value?.scrollBy({ left: 300, behavior: 'smooth' })
}
// 向左移动
function moveToleft() {
  console.log('moveToleft', containner.value)
  containner.value?.scrollBy({ left: -300, behavior: 'smooth' })
}
onMounted(() => {
  renderChart()
  // 自适应容器尺寸
  if (chartRef.value && 'ResizeObserver' in window) {
    resizeObserver = new ResizeObserver(() => chartInstance && chartInstance.resize())
    resizeObserver.observe(chartRef.value)
  } else {
    window.addEventListener('resize', () => chartInstance && chartInstance.resize())
  }
})

onBeforeUnmount(() => {
  if (resizeObserver && chartRef.value) {
    resizeObserver.unobserve(chartRef.value)
    resizeObserver.disconnect()
  }
  disposeChart()
})

// 当用户切换"日期卡片"或"指标类型"时，刷新图表
watch([selectedIdx, metricType], () => {
  renderChart()
})

// 计算当日最高数据以及最低数据
function calculateDailyMaxMin(hourlyData: Hourly[] | null, dateIndex: number, metricType: string) {
  if (metricType === '概览' || !hourlyData) return { Max: 0, Min: 0 }

  // 计算时间分片
  const startIndex = dateIndex * 24
  const endIndex = Math.min(startIndex + 24, hourlyData.length)
  const dailyData = hourlyData.slice(startIndex, endIndex)
  const TypeMap = {
    降水: 'precip',
    风速: 'windSpeed',
    湿度: 'humidity',
    云量: 'cloud',
    气压: 'pressure',
  }
  const TypeValue = TypeMap[metricType as keyof typeof TypeMap]

  // 最高数据
  let Max = 0
  // 最低数据
  let Min = 0
  const values = dailyData
    .filter((item) => item[TypeValue] !== undefined && item[TypeValue] !== null)
    .map((item) => parseFloat(item[TypeValue]))

  if (values.length > 0) {
    Max = Math.max(...values)
    Min = Math.min(...values)
  }

  return { Max, Min }
}

// 为每一天创建计算属性缓存
const dailyMaxMinCache = computed(() => {
  const cache: Record<string, { Max: number; Min: number }> = {}

  if (!HourlyWeather.value?.hourly || metricType.value === '概览') {
    return cache
  }

  // 为每一天计算并缓存最大值和最小值
  for (let i = 0; i < (future.value?.length || 0); i++) {
    cache[i] = calculateDailyMaxMin(HourlyWeather.value.hourly, i, metricType.value)
  }

  return cache
})
</script>
<style scoped lang="scss">
@use './defaultstyle.scss' as *;
@use './morerain.scss' as *;
html.dark {
  .main
    .tabsCarouselItems
    .tabsContainer
    .tabsCarousel
    .tabsCarouselItems-DS.active
    .tabDailyItem-DS
    .tabDailyButton {
    background: rgba(255, 255, 255, 0.45);
  }
  // 如果是暗色模式下，则取消降水样式
  .main
    .tabsCarouselItems
    .tabsContainer
    .tabsCarousel
    .tabsCarouselItems-DS.active
    .tabDailyItem-DS
    .tabDailyButton
    .tabContent
    .rain
    .right {
    border: none;
  }

  .main
    .tabsCarouselItems
    .tabsContainer
    .tabsCarousel
    .tabsCarouselItems-DS.active
    .tabDailyItem-DS::before {
    box-shadow: 0 0 0 16px rgba(255, 255, 255, 0.45);
    left: -32px;
  }
  .main
    .tabsCarouselItems
    .tabsContainer
    .tabsCarousel
    .tabsCarouselItems-DS.active
    .tabDailyItem-DS::after {
    box-shadow: 0 0 0 16px rgba(255, 255, 255, 0.45);
  }
  .illustration-T {
    background: rgba(255, 255, 255, 0.45) !important;
  }
}
//媒体查询
@media (max-width: 1200px) {
  .main {
    .title {
      .titleContainer {
        max-width: 36rem;
      }
    }

    .illustration {
      height: 26rem;
    }
  }
}

@media (max-width: 992px) {
  .main {
    .title {
      flex-direction: column;
      align-items: flex-start;
      gap: 8px;
      .titleText {
        margin-right: 0;
        font-size: 16px;
      }
      .titleContainer {
        max-width: 100%;
        .el-radio-group {
          flex-wrap: wrap;
          row-gap: 8px;
          column-gap: 8px;
        }
      }
    }
    .tabsCarouselItems {
      column-gap: 8px;

      .illustration {
        height: 22rem;
      }
    }
  }
}

@media (max-width: 768px) {
  .main {
    padding: 8px 0;
    .tabsCarouselItems {
      column-gap: 8px;
      overflow: visible;

      .illustration {
        height: 18rem;
      }
    }
  }

  .inner {
    .title span,
    .content .text span {
      font-size: 14px;
    }
  }
}
</style>
